import geojsonvt from '../../ThirdParty/geojson-vt/index';
import Geojson from 'ol/format/GeoJSON';

const replacer = function (key, value) {
  if (!value || !value.geometry) {
    return value;
  }

  let type;
  const rawType = value.type;

  let geometry = value.geometry;

  if (rawType === 1) {
    type = 'MultiPoint';
    if (geometry.length === 1) {
      type = 'Point';
      geometry = geometry[0];
    }
  } else if (rawType === 2) {
    type = 'MultiLineString';
    if (geometry.length === 1) {
      type = 'LineString';
      geometry = geometry[0];
    }
  } else if (rawType === 3) {
    type = 'Polygon';
    if (geometry.length > 1) {
      type = 'MultiPolygon';
      geometry = [geometry];
    }
  }

  return {
    type: 'Feature',
    geometry: {
      type,
      coordinates: geometry,
    },
    properties: value.tags,
  };
};

class GeojsonVtTileIndex {
  tileIndex: any
  format: Geojson
  constructor(json, geographicTiling: boolean = false) {
    this.tileIndex = geojsonvt(json, {
      maxZoom: 22,
      tolerance: 0, // simplification tolerance (higher means simpler)
      extent: 4096, // tile extent (both width and height)
      buffer: 128,   // tile buffer on each side
      debug: 0,     // logging level (0 to disable, 1 or 2)
      lineMetrics: true, // whether to enable line metrics tracking for LineString/MultiLineString features
      promoteId: null,    // name of a feature property to promote to feature.id. Cannot be used with `generateId`
      generateId: false,  // whether to generate feature ids. Cannot be used with `promoteId`
      indexMaxZoom: 15,       // max zoom in the initial tile index
      indexMaxPoints: 100000, // max number of points per tile in the index
      geographicTiling,
    })
    this.format = new Geojson()
  }

  fetchFeatures(x, y, z) {
    const data = this.tileIndex.getTile(z, x, y);
    const geojson = JSON.stringify({
      type: 'FeatureCollection',
      features: data ? data.features : [],
    }, replacer);
    const features = this.format.readFeatures(geojson)
    const e = this.tileIndex.options.extent
    return Promise.resolve({ features, extent: [0, 0, e, e] })
  }
}

export default GeojsonVtTileIndex
